interface ParamChecker {
  rule: Function
  desc: string
}
export const dbEnvChecker = () => {
  if (!window.indexedDB) {
    throw new Error("Your browser doesn't support a stable version of IndexedDB. Such and such feature will not be available.")
  }
}
const isObject = (val: unknown) => val && typeof val === 'object'
const isString = (val: unknown) => typeof val === 'string'
const isArray = Array.isArray
const isBoolean = (val: unknown) => typeof val === 'boolean'
const isPositiveInteger = (x: any) => !isNaN(x) && x >= 0

export const ParamCheckerEnum = {
  NonNegativeInteger: {
    rule: isPositiveInteger,
    desc: 'needs to be a non-negative integer',
  },
  NotNullObject: {
    rule: isObject,
    desc: 'needs to be a not-null object',
  },
  String: {
    rule: isString,
    desc: 'needs to be a string',
  },
  Array: {
    rule: isArray,
    desc: 'nees to be an Array',
  },
  Boolean: {
    rule: isBoolean,
    desc: 'needs to be a boolean',
  },
}

export function optionWithBackup (param:any, backup:any) {
  return param !== undefined ? param : backup
}

export function paramChecker (
  param:any,
  checker:ParamChecker,
  paramName:string,
  optional:boolean,
) {
  const exp = `${paramName} ${checker.desc}`
  if (optional) {
    if (param !== undefined && !checker.rule(param)) {
      throw new Error(`${exp} if defined`)
    }
  } else {
    if (!checker.rule(param)) {
      throw new Error(exp)
    }
  }
}

export function deduplicateList (list:any[]) {
  const deduplicatedList = list.reduce((accumulator, currentItem) => {
    if (accumulator.indexOf(currentItem) < 0) {
      return accumulator.concat(currentItem)
    } else {
      return accumulator
    }
  }, [])
  return deduplicatedList
}
